#!/usr/bin/python
# -*- coding: utf-8 -*-
#Create Time : 2006 2006-6-18 0:22:41
#Create By User :

# Program infomation

from base64 import urlsafe_b64decode, urlsafe_b64encode
from random import sample
from utils import uuid
import os.path
import glob
import re
import cylons_config
import dircache

# use show models in my script
import sys
sys.path.append( cylons_config.CONF_SITE_PATH )
os.environ["DJANGO_SETTINGS_MODULE"] = "Cylons2.settings"
from show import models

#===============================================================================
# debuger
#===============================================================================
import sys
debugToggle = 1
def show_debug( *values ):
    if debugToggle == 0: return
    print >> sys.stderr, ">", 
    for v in values: print >> sys.stderr, v, 
    print >> sys.stderr, '.'

#===============================================================================
#encode & decode path with base64
#===============================================================================
def p2e( s ):
    '''
    encode path to base64 code
    @param path_str:
    '''

    return urlsafe_b64encode( s )

def e2p( s ):
    '''
    decode base64 str to path
    @param str_path:
    '''

    try:
        return urlsafe_b64decode( s )
    except TypeError:
        raise TypeError

#===============================================================================
# directory and file test
#===============================================================================
def isDirectory( p ):
    '''

    @param p: path
    '''

    if os.path.isdir( p ):
        return True
    else:
        return False

def isFile( p ):
    '''

    @param p: path
    '''

    if os.path.isfile( p ):
        return True
    else:
        return False

def hasForbidden( p ):
    '''

    @param p: path of media directory
    '''

    forbidden_file = os.path.join( p, 'forbidden.html' )
    if isFile( forbidden_file ):
        return True
    else:
        try:
            _f = open( forbidden_file, 'w' )
            _f.close()
            return True
        except IOError:
            return False

def hasIntro( p ):
    '''

    @param p: path of media directory
    '''

    intro_file = os.path.join( p, 'intro.html' )
    if isFile( intro_file ):
        return True
    else:
        try:
            _f = open( intro_file, 'w' )
            _f.close()
            return True
        except IOError:
            return False
        
re_audio = re.compile( cylons_config.CONF_AUDIO_EXT )
re_video = re.compile( cylons_config.CONF_VIDEO_EXT )
re_cover = re.compile( cylons_config.CONF_COVER_EXT )

def filterOneExt( f, t ):
    '''
    
    @param f: file name
    @param t: type a=audio ,v=video, c=cover
    '''    
    _t = t.lower()
    _ext_name = os.path.splitext( f )[1]
    if _t=='a' or _t=='audio':
        if re_audio.search( _ext_name ):return True
    if _t=='v' or _t=='video':
        if re_video.search( _ext_name ):return True
    if _t=='c' or _t=='cover':
        if re-cover.search( _ext-name ):return True
    return False
    
    
#===============================================================================
#def filterListExt( l, p ):
#    '''
#
#    @param l: dir file list
#    @param pattern: regex pattern
#    '''
#    _cre = re.compile( p )
#    _tmp_file_list = []
#    for x in l:
#        _ext_name = os.path.splitext( x )[1]
#        if _cre.search( _ext_name ):
#            _tmp_file_list.append( x )
#        else:
#            pass
#    return _tmp_file_list
#===============================================================================

def filterListExt( l, t ):
    '''
    
    @param l: directory list
    @param t: t filter type
    '''
    _t = t.lower()
    
    if _t=='a' or _t=='audio':
        _tmp_file_lists = []
        for x in l :
            _ext_name = os.path.splitext( x )[1]
            if re_audio.search( _ext_name ): 
                _tmp_file_lists.append( x )
    if _t=='v' or _t=='video':
        _tmp_file_lists = []
        for x in l :
            _ext_name = os.path.splitext( x )[1]
            if re_video.search( _ext_name ): 
                _tmp_file_lists.append( x )
    if _t=='c' or _t=='cover':
        _tmp_file_lists = []
        for x in l :
            _ext_name = os.path.splitext( x )[1]
            if re_cover.search( _ext_name ): 
                _tmp_file_lists.append( x )
    return _tmp_file_lists
    

def hasMediaCover( p ):
    '''check media path has cover ? return file name 

    @param p: path 
    '''
    from random import sample
    _current_path = p 
    _current_dir_lists = dircache.listdir( _current_path ) # use cached directory list
    _cover_lists = filterListExt( _current_dir_lists, 'c' )
    if len( _cover_lists ) == 0:
        return ''
    else:
        return os.path.join( p, sample( _cover_lists, 1 )[0] )
    
def getMediaCover( i ):
    ''' get media cover path from media table
    
    @param i: uuid
    '''
    
    pass

def getMediaPathByUUID( i ):
    ''' get media path from media table
    
    @param i: media uuid
    '''
    #print i
    res = models.MediaTable.objects.filter( media_uuid__iexact=i )
    #print res
    if res.count() == 0 : # not found record in table
        return None
    else:
        return res[0].media_path


#===============================================================================
# make a uuid string
# this func usually used by mark a directory tag
#===============================================================================
def getUUIDStr():
    try:
        return uuid.get_time( uuid )
    except:
        _s = '0123456789abcdef' # 16 bit
        _8b0 = ''.join( '%s' % x for x in sample( _s, 8 ) )
        _4b1 = ''.join( '%s' % x for x in sample( _s, 4 ) )
        _4b2 = ''.join( '%s' % x for x in sample( _s, 4 ) )
        _4b3 = ''.join( '%s' % x for x in sample( _s, 4 ) )
        _12b4 = ''.join( '%s' % x for x in sample( _s, 12 ) )
        return _8b0+'-'+_4b1+'-'+_4b2+'-'+_4b3+'-'+_12b4

def markUUIDFile( p, i ):
    '''

    @param p: path
    @param i: uuid str
    '''


    _uuid_file_name = os.path.join( p, i )
    try:
        fp = open( _uuid_file_name, 'w' )
        fp.close()
        return True
    except IOError:
        return False

def addMediaByPath( p, i ):
    '''add a path to media table
            mark uuid in path,
            fill media uuid in media table
            fill media path in medie table
            check has media cover , if has then fill media cover path in media table

    @param p: path of media
    @param i: media uuid
    '''
    _media_name = os.path.basename( p )
    _media_uuid = i
    _media_cover = hasMediaCover( p )
    _media_path = p
    m = models.MediaTable( media_name=_media_name, \
                           media_uuid=_media_uuid, \
                           media_path=_media_path, \
                           media_cover=_media_cover )
    m.save()

def deleteMediaByUUID( i ):
    ''' find uuid in media in media table , delete it

    @param i: uuid
    '''
    #delete uuid in Media table
    res = models.MediaTable.objects.filter( media_uuid=i )
    show_debug( 'delete %s' % i )
    res.delete()
    re.save()


def deleteMediaUUIDFile( p, i ):
    '''

    @param p: path
    @param i: uuid name
    '''

    _uuid_path = os.path.join( p, i )
    try:
        os.remove( _uuid_path )
        show_debug( 'delete uuid file %s' % _uuid_path )
    except IOError:
        show_debug( 'delete Error %s' % _uuid_path )


# uuid regex compile object
uuid_re = re.compile( r'''[0-9a-fA-F]{8}\-[0-9a-fA-F]{4}\-[0-9a-fA-F]{4}\-[0-9a-fA-F]{4}\-[0-9a-fA-F]{12}''' )

def getMediaIDFile( p ):
    _current_path = p
    os.chdir( _current_path )
    _uuid_file_lists = glob.glob( '????????-????-????-????-????????????' )
    _found_uuid_number = len( _uuid_file_lists )
    if _found_uuid_number == 0 :
        return None
    else:
        return _uuid_file_lists
    
def hasMediaID( p ):
    '''sample uuid = '{6ba7b810-9dad-11d1-80b4-00c04fd430c8}'

    @param p:
    this func has a lot of jot to do
        check has uuid
        if has a lot of uuid , then ix it
        if has uuid , then check path is vaild?

    '''
    _current_path = p
    os.chdir( _current_path )
    _uuid_file_lists = glob.glob( '????????-????-????-????-????????????' )
    _found_uuid_number = len( _uuid_file_lists )
    if _found_uuid_number == 0:# not found uuid tag, add it
        show_debug( 'NO UUID' )

        # try to add media infomation into media tables

        #gen uuid
        _i = getUUIDStr()
        #mark uudi file in directory
        markUUIDFile( _current_path, _i )
        #inster record in media table
        addMediaByPath( _current_path, _i )
    elif _found_uuid_number > 1: #has many of uuid tag, need clean all uuid ,and readd it
        show_debug( 'HAS A LOT OF UUID' )
        # try to clean media directory
        for x in _uuid_file_lists:
            # delete uuid file
            deleteMediaUUIDFile( _current_path, x )
            # delete media uuid in media table
            deleteMediaByUUID( x )

        # when clean uuid file ,and clean uuid in media table , then readd it

        #gen uuid
        _i = getUUIDStr()
        #mark uudi file in directory
        markUUIDFile( _current_path, _i )
        #inster record in media table
        addMediaByPath( _current_path, _i )
    elif _found_uuid_number == 1:
        show_debug( 'FOUND UUID' ) # uuid is vaild, do nothing
        _u = _uuid_file_lists[0]
        #print _u
        _p = getMediaPathByUUID( _u )
        #print _p
        if _p == _current_path:
            show_debug('Check Media path OK')
        elif _p == None:
            # clean uuid file , readd 
            deleteMediaUUIDFile( _current_path, _u )
            # readd 
            #gen uuid
            _i = getUUIDStr()
            #mark uudi file in directory
            markUUIDFile( _current_path, _i )
            #inster record in media table
            addMediaByPath( _current_path, _i )
        else: 
            #TAG: need clean uuid file and del record uuid
            pass
        
#===============================================================================
#        #TAG: need to check uuid is vaild
#===============================================================================
    else:
        show_debug( 'SOME OTHER' ) # .......

def test():
    #dorp table
    models.MediaTable.objects.all().delete()
    models.RecommendMedia.objects.all().delete()

    u = getUUIDStr()

    #inster data
    test_media = models.MediaTable( media_uuid=u, media_name='123456', media_path='c:', media_cover='sdf' )
    test_media.save()

    s = models.RecommendMedia( media_uuid=test_media )
    s.save()

    a = models.MediaTable.objects.all() #@PydevCodeAnalysisIgnore
    for x in a:
        print x.media_uuid, 'media table'

    b = models.RecommendMedia.objects.filter( media_uuid=u )
    for x in b :
        print x.media_uuid, 're tab'

    models.MediaTable.objects.all().delete()

    c = models.RecommendMedia.objects.all()
    #print c.get().media_uuid
    print c

if __name__ == '__main__':
    #test()
    pass